
package com.hlkj.pay.app.merchant.ext.impl.huifu.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantAccessContext;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantAccessQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantAccessSignContext;
import com.hlkj.pay.app.merchant.ext.impl.huifu.constant.HuiFuConstant;
import com.hlkj.pay.app.merchant.ext.impl.huifu.dto.HuiFuAccessExtentDto;
import com.hlkj.pay.app.merchant.ext.impl.huifu.dto.HuiFuConfig;
import com.hlkj.pay.app.merchant.ext.impl.huifu.handler.params.*;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;
import com.huifu.bspay.sdk.opps.client.BasePayClient;
import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
import com.huifu.bspay.sdk.opps.core.request.*;
import com.huifu.bspay.sdk.opps.core.utils.DateTools;
import com.huifu.bspay.sdk.opps.core.utils.SequenceTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * @author HlpayTeam
 * @date 2024/09/26 12:02
 */
@Slf4j
public class HuiFuMerchantRequestHandle {

    /**
     * 企业进件
     *
     * @param channelMerchantAccessContext
     */
    static void companyAccess(HuiFuConfig huiFuConfig, ChannelMerchantAccessContext channelMerchantAccessContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        // 1. 数据初始化
        MerConfig merConfig = HuiFuMerchantAccessCompanyParamsHandle.merConfig(huiFuConfig);
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        channelMerchantAccessContext.setPayChannelRequestDO(payChannelRequestDO);
        try {
            BasePay.initWithMerConfig(merConfig);
            // 参数组装
            Map<String, Object> response;
            // 判断是新增还是编辑    进件失败无法调用修改 汇付那边数据有问题
//            if (StringUtils.hasText(merchantAccessInfoDO.getSubMchId())) {
//                HuiFuMerchantAccessCompanyParamsHandle.addProcessFileId(channelMerchantAccessContext);
//                // 编辑 与新增参数一致 需要进行参数转换
//                V2MerchantBasicdataModifyRequest basicdataEntRequest = HuiFuMerchantAccessCompanyParamsHandle.v2MerchantBusiModify(channelMerchantAccessContext);
//                basicdataEntRequest.setUpperHuifuId(huiFuConfig.getUpperHuifuId());
//                basicdataEntRequest.setHuifuId(merchantAccessInfoDO.getSubMchId());
//                // 记录请求参数
//                payChannelRequestDO.setRequestId(basicdataEntRequest.getReqSeqId());
//                payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(basicdataEntRequest));
//                payChannelRequestDO.setRequestUrl(basicdataEntRequest.getFunctionCode().getCode());
//                payChannelRequestDO.setRequestTime(System.currentTimeMillis());
//                // 发起请求
//                log.info("斗拱企业开户修改 请求参数 request:{}", JsonUtils.toJsonString(basicdataEntRequest));
//                response = BasePayClient.request(basicdataEntRequest, false);
//                payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
//                log.info("斗拱企业开户修改 返回参数 response:{}", payChannelRequestDO.getResponse());
//            }
//            else {
                HuiFuMerchantAccessCompanyParamsHandle.addProcessFileId(channelMerchantAccessContext);
                // 新增参数转换
                V2MerchantBasicdataEntRequest v2MerchantBasicdataEntRequest = HuiFuMerchantAccessCompanyParamsHandle.v2UserBasicdataEntRequest(channelMerchantAccessContext);
                v2MerchantBasicdataEntRequest.setUpperHuifuId(huiFuConfig.getUpperHuifuId());
                // 记录请求参数
                payChannelRequestDO.setRequestId(v2MerchantBasicdataEntRequest.getReqSeqId());
                payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(v2MerchantBasicdataEntRequest));
                payChannelRequestDO.setRequestUrl(v2MerchantBasicdataEntRequest.getFunctionCode().getCode());
                payChannelRequestDO.setRequestTime(System.currentTimeMillis());
                // 发起请求
                log.info("斗拱企业开户提交 请求参数 request:{}", JsonUtils.toJsonString(v2MerchantBasicdataEntRequest));
                response = BasePayClient.request(v2MerchantBasicdataEntRequest, false);
                payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
                log.info("斗拱企业开户提交 返回参数 response:{}", payChannelRequestDO.getResponse());
//            }
            processResultData(response, channelMerchantAccessContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            channelMerchantAccessContext.setRemark("斗拱企业开户提交 请求失败,失败信息" + e.getMessage());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
        }
    }

    /**
     * 个人进件
     *
     * @param channelMerchantAccessContext
     */
    static void personAccess(HuiFuConfig huiFuConfig, ChannelMerchantAccessContext channelMerchantAccessContext) {
        // 1. 数据初始化
        MerConfig merConfig = HuiFuMerchantAccessCompanyParamsHandle.merConfig(huiFuConfig);
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        channelMerchantAccessContext.setPayChannelRequestDO(payChannelRequestDO);
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            BasePay.initWithMerConfig(merConfig);
            // 参数组装
            Map<String, Object> response;
            // 判断是新增还是编辑  进件失败无法调用修改 汇付那边数据有问题
//            if (StringUtils.hasText(merchantAccessInfoDO.getSubMchId())) {
//                HuiFuMerchantAccessCompanyParamsHandle.addProcessFileId(channelMerchantAccessContext);
//                // 编辑 与新增参数一致 需要进行参数转换
//                V2MerchantBasicdataModifyRequest basicdataEntRequest = HuiFuMerchantAccessCompanyParamsHandle.v2MerchantBusiModify(channelMerchantAccessContext);
//                basicdataEntRequest.setUpperHuifuId(huiFuConfig.getUpperHuifuId());
//                basicdataEntRequest.setHuifuId(merchantAccessInfoDO.getSubMchId());
//                // 记录请求参数
//                payChannelRequestDO.setRequestId(basicdataEntRequest.getReqSeqId());
//                payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(basicdataEntRequest));
//                payChannelRequestDO.setRequestUrl(basicdataEntRequest.getFunctionCode().getCode());
//                payChannelRequestDO.setRequestTime(System.currentTimeMillis());
//                // 发起请求
//                log.info("斗拱小微开户修改 请求参数 request:{}", JsonUtils.toJsonString(basicdataEntRequest));
//                response = BasePayClient.request(basicdataEntRequest, false);
//                payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
//                log.info("斗拱小微开户修改 返回参数 response:{}", payChannelRequestDO.getResponse());
//            }
//            else {
                HuiFuMerchantAccessPersonParamsHandle.addProcessFileId(channelMerchantAccessContext);
                // 新增参数转换
                V2MerchantBasicdataIndvRequest v2MerchantBasicdataEntRequest = HuiFuMerchantAccessPersonParamsHandle.v2UserBasicdataIndvRequest(channelMerchantAccessContext);
                v2MerchantBasicdataEntRequest.setUpperHuifuId(huiFuConfig.getUpperHuifuId());
                // 记录请求参数
                payChannelRequestDO.setRequestId(v2MerchantBasicdataEntRequest.getReqSeqId());
                payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(v2MerchantBasicdataEntRequest));
                payChannelRequestDO.setRequestUrl(v2MerchantBasicdataEntRequest.getFunctionCode().getCode());
                payChannelRequestDO.setRequestTime(System.currentTimeMillis());
                // 发起请求
                log.info("斗拱小微开户 请求参数 request:{}", JsonUtils.toJsonString(v2MerchantBasicdataEntRequest));
                response = BasePayClient.request(v2MerchantBasicdataEntRequest, false);
                log.info("斗拱小微开户 返回参数 response:{}", JsonUtils.toJsonString(response));
//            }

            payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
            processResultData(response, channelMerchantAccessContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            channelMerchantAccessContext.setRemark("斗拱个人开户 请求失败,失败信息" + e.getMessage());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
        }
    }

    /**
     * 返回信息处理
     *
     * @param response
     * @param channelMerchantAccessContext
     */
    static void processResultData(Map<String, Object> response, ChannelMerchantAccessContext channelMerchantAccessContext) {
        if (CollectionUtils.isEmpty(response)) {
            channelMerchantAccessContext.setRemark("斗拱个人开户返回信息为空");
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
            return;
        }
        PayChannelRequestDO payChannelRequestDO = channelMerchantAccessContext.getPayChannelRequestDO();
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        // 参数组装
        // Map<String,Object> data = (Map<String,Object>)response.get("data");
        String respCode = response.get("resp_code").toString();
        if (response.containsKey("huifu_id")) {
            merchantAccessInfoDO.setSubMchId(response.get("huifu_id").toString());
            //用于返回失败时修改子商户号
            channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo().setSubMchId(response.get("huifu_id").toString());
        }

        if (HuiFuConstant.ACCESS_SUCCESS_CODE.equals(respCode) || HuiFuConstant.DOING_SUCCESS_CODE.equals(respCode)) {
            Object applyNo = response.get("apply_no");
            if (applyNo != null) {
                payChannelRequestDO.setApplyNo(applyNo.toString());
                merchantAccessInfoDO.setApplyNo(applyNo.toString());
            }
            Object tokenNo = response.get("token_no");
            if (tokenNo != null) {
                HuiFuAccessExtentDto huiFuAccessExtentDto=new HuiFuAccessExtentDto();
                huiFuAccessExtentDto.setTokenNo(tokenNo.toString());
                merchantAccessInfoDO.setExtendA(JsonUtils.toJsonString(huiFuAccessExtentDto));
            }

            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE);
            channelMerchantAccessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SUBMIT);
        }
        else {
            String respDesc = response.get("resp_desc").toString();
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
            if (StringUtils.hasText(respDesc)) {
                channelMerchantAccessContext.setRemark(respDesc);
            }
            else {
                channelMerchantAccessContext.setRemark("斗拱个人开户返回错误信息为空,错误码为:" + respCode);
            }

        }
    }

    /**
     * 业务开通
     *
     * @param huiFuConfig
     * @param channelMerchantBusinessContext
     */
    public static void businessOpenRequest(HuiFuConfig huiFuConfig, ChannelMerchantAccessContext channelMerchantBusinessContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            // 1. 数据初始化
            MerConfig merConfig = HuiFuMerchantAccessCompanyParamsHandle.merConfig(huiFuConfig);
            BasePay.initWithMerConfig(merConfig);
            // 2.组装请求参数
            CommonResult<V2MerchantBusiOpenRequest> commonResult = HuiFuMerchantOpenRequestParamsHandle.v2MerchantBusiOpenRequest(channelMerchantBusinessContext);
            if (!commonResult.isSuccess()) {
                channelMerchantBusinessContext.setRemark("斗拱业务开通参数校验失败" + commonResult.getMsg());
                channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            V2MerchantBusiOpenRequest request = commonResult.getData();
            // 汇付客户Id
            request.setHuifuId(merchantAccessInfoDO.getSubMchId());
            request.setUpperHuifuId(merConfig.getHuifuId());
            PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
            // payChannelRequestDO.setAccessStatus(merchantAccessInfoDO.getStatus());
            payChannelRequestDO.setRequestUrl(request.getFunctionCode().getCode());
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(request));
            payChannelRequestDO.setRequestTime(System.currentTimeMillis());
            log.info("斗拱业务开通 请求参数 request:{}", JsonUtils.toJsonString(request));
            // 3. 发起API调用
            Map<String, Object> response = BasePayClient.request(request, false);
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
            payChannelRequestDO.setRequestUrl(request.getFunctionCode().getCode());
            channelMerchantBusinessContext.setPayChannelRequestDO(payChannelRequestDO);
            log.info("斗拱业务开通 返回信息 response:{}", payChannelRequestDO.getResponse());
            HuiFuMerchantConfigParamsHandle.businessOpenProcess(response, channelMerchantBusinessContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("斗拱业务开通 请求失败 message:{}", e.getMessage(), e);
            channelMerchantBusinessContext.setRemark("斗拱业务开通 请求失败,失败信息" + e.getMessage());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
        }
    }

    /**
     * 业务查询
     * 
     * @param huiFuConfig
     * @param channelMerchantAccessQueryContext
     */
    public static void accessQueryRequest(HuiFuConfig huiFuConfig, ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessQueryContext.getMerchantAccessInfo();
        try {
            // 1. 数据初始化
            MerConfig merConfig = HuiFuMerchantAccessCompanyParamsHandle.merConfig(huiFuConfig);
            BasePay.initWithMerConfig(merConfig);
            // 2.组装请求参数
            V2MerchantBasicdataStatusQueryRequest request = new V2MerchantBasicdataStatusQueryRequest();
            // 请求流水号
            request.setReqSeqId(SequenceTools.getReqSeqId32());
            // 请求日期
            request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
            // 申请单
            request.setApplyNo(merchantAccessInfoDO.getApplyNo());
            // 汇付客户Id
            request.setHuifuId(merchantAccessInfoDO.getSubMchId());
            // payChannelRequestDO.setAccessStatus(merchantAccessInfoDO.getStatus());
            // 3. 发起API调用
            log.info("斗拱查询开户 请求参数 request:{}", JsonUtils.toJsonString(request));
            Map<String, Object> response = BasePayClient.request(request, false);
            log.info("斗拱查询开户 返回信息 response:{}", JsonUtils.toJsonString(response));
            HuiFuMerchantResponseParamsHandle.merchantAccessQueryParamsProcess(response, channelMerchantAccessQueryContext);


        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("斗拱查询开户 请求失败 message:{}", e.getMessage(), e);
            channelMerchantAccessQueryContext.setRemark("斗拱查询开户 请求失败,失败信息" + e.getMessage());
            channelMerchantAccessQueryContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    /**
     * 业务查询
     * 
     * @param huiFuConfig
     * @param channelMerchantAccessQueryContext
     */
    public static void signQueryRequest(HuiFuConfig huiFuConfig, ChannelMerchantAccessSignContext channelMerchantAccessQueryContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessQueryContext.getMerchantAccessInfoDO();
        try {
            // 1. 数据初始化
            MerConfig merConfig = HuiFuMerchantAccessCompanyParamsHandle.merConfig(huiFuConfig);
            BasePay.initWithMerConfig(merConfig);
            // 2.组装请求参数
            V2MerchantBasicdataStatusQueryRequest request = new V2MerchantBasicdataStatusQueryRequest();
            // 请求流水号
            request.setReqSeqId(SequenceTools.getReqSeqId32());
            // 请求日期
            request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
            // 申请单
            request.setApplyNo(merchantAccessInfoDO.getApplyNo());
            // 汇付客户Id
            request.setHuifuId(merchantAccessInfoDO.getSubMchId());
            PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
            // payChannelRequestDO.setAccessStatus(merchantAccessInfoDO.getStatus());
            payChannelRequestDO.setRequestUrl(request.getFunctionCode().getCode());
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(request));
            payChannelRequestDO.setRequestTime(System.currentTimeMillis());
            // 3. 发起API调用
            log.info("斗拱查询开户签约 请求参数 request:{}", JsonUtils.toJsonString(request));
            Map<String, Object> response = BasePayClient.request(request, false);
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
            payChannelRequestDO.setRequestUrl(request.getFunctionCode().getCode());
            channelMerchantAccessQueryContext.setPayChannelRequestDO(payChannelRequestDO);
            log.info("斗拱查询开户签约 返回信息 response:{}", payChannelRequestDO.getResponse());
            HuiFuMerchantResponseParamsHandle.merchantAccessSignQueryParamsProcess(response, channelMerchantAccessQueryContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("斗拱查询开户签约 请求失败 message:{}", e.getMessage(), e);
            channelMerchantAccessQueryContext.setRemark("斗拱查询开户签约 请求失败,失败信息" + e.getMessage());
            channelMerchantAccessQueryContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }

    }

    public static void businessUpdateRequest(HuiFuConfig huiFuConfig, ChannelMerchantAccessContext channelMerchantBusinessContext) {
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            // 1. 数据初始化
            MerConfig merConfig = HuiFuMerchantAccessCompanyParamsHandle.merConfig(huiFuConfig);
            BasePay.initWithMerConfig(merConfig);
            // 2.组装请求参数
            CommonResult<V2MerchantBusiModifyRequest> commonResult = HuiFuMerchantOpenRequestParamsHandle.v2MerchantBusiModifyRequest(channelMerchantBusinessContext);
            if (!commonResult.isSuccess()) {
                channelMerchantBusinessContext.setRemark("斗拱业务修改参数校验失败" + commonResult.getMsg());
                channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
                return;
            }
            V2MerchantBusiModifyRequest request = commonResult.getData();
            // 汇付客户Id
            request.setHuifuId(merchantAccessInfoDO.getSubMchId());
            PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
            // payChannelRequestDO.setAccessStatus(merchantAccessInfoDO.getStatus());
            payChannelRequestDO.setRequestUrl(request.getFunctionCode().getCode());
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(request));
            payChannelRequestDO.setRequestTime(System.currentTimeMillis());
            log.info("斗拱业务修改 请求参数 request:{}", JsonUtils.toJsonString(request));
            // 3. 发起API调用
            Map<String, Object> response = BasePayClient.request(request, false);
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(response));
            payChannelRequestDO.setRequestUrl(request.getFunctionCode().getCode());
            channelMerchantBusinessContext.setPayChannelRequestDO(payChannelRequestDO);
            log.info("斗拱业务修改 返回信息 response:{}", payChannelRequestDO.getResponse());
            HuiFuMerchantConfigParamsHandle.businessOpenProcess(response, channelMerchantBusinessContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("斗拱业务修改 请求失败 message:{}", e.getMessage(), e);
            channelMerchantBusinessContext.setRemark("斗拱业务开通 请求失败,失败信息" + e.getMessage());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
        }
    }
}
